home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / filesyst / thsfs.tgz / thsfs.tar / thsfs / transfer.c < prev    next >
C/C++ Source or Header  |  1994-10-04  |  6KB  |  349 lines

  1. /*************************************************************
  2.  *                                                           *
  3.  *    ths  Filesystem                  04.10.94      V1.1    *
  4.  *                                                           *
  5.  *    Thomas Scheuermann     ths@ai-lab.fh-furtwangen.de     *
  6.  *                                                           *
  7.  *************************************************************/
  8.  
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/sched.h>
  12. #include <linux/errno.h>
  13. #include <linux/string.h>
  14. #include <linux/stat.h>
  15. #include <linux/mm.h>
  16. #include <linux/locks.h>
  17. #include <linux/fs.h>
  18. #include <linux/malloc.h>
  19.  
  20. #include <asm/system.h>
  21. #include <asm/segment.h>
  22. #include <asm/bitops.h>
  23.  
  24. #include "ths.h"
  25. #include "ths_i.h"
  26.  
  27.  
  28. /*
  29.  * Lesen eines bestimmten Sektors
  30.  */
  31.  
  32. int ths_read_sektor(struct super_block *s, unsigned long sektor, struct ths_buffer *tbf)
  33. {
  34.     int i,j;
  35.     unsigned char *data,*data1=NULL;
  36.     struct ths_sb_info *ths_sb;
  37.     struct buffer_head *bh;
  38.  
  39. #ifdef DEBUG
  40.     printk("ths_read_sektor : %ld\n",sektor);
  41. #endif
  42.  
  43.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  44.  
  45.     tbf->sektore = 1;
  46.  
  47.     j=0;
  48.     if(sektor & 0x01)
  49.         j = 512;
  50.  
  51.     tbf->hl[0]=j;
  52.     tbf->dirty=0;
  53.  
  54.     if(!(tbf->data[0]=(unsigned char *)kmalloc(512,GFP_KERNEL)))
  55.     {
  56.         printk("No Memory left !\n");
  57.         return -1;
  58.     }
  59.  
  60. /*
  61.  * Datenumsetzung
  62.  */
  63.  
  64.     switch(ths_sb->art)
  65.     {
  66.         case 0:
  67.             if(!(bh = bread(s->s_dev,sektor>>1,BLOCK_SIZE)))
  68.             {
  69.                 printk("bread-Fehler\n");
  70.                 return -1;
  71.             }
  72.             tbf->bnr[0] = sektor>>1;
  73.             data1 = &bh->b_data[j];
  74.             break;
  75.         case 1:
  76.             data1 = ths_uread(s,sektor,&bh);
  77.             break;
  78.     }
  79.  
  80.     tbf->sektnr[0] = sektor;
  81.     tbf->cluster=0;
  82.     data = tbf->data[0];
  83.     for(i=0;i<512;i++)
  84.     {
  85.         data[i] = data1[i];
  86.     }
  87.  
  88.     brelse(bh);
  89.     return 0;
  90. }
  91.  
  92.  
  93. /*
  94.  * Speicher freigeben nach dem Lesen eines Sektors
  95.  */
  96.  
  97. void ths_free_sektor(struct ths_buffer *tbf)
  98. {
  99. #ifdef DEBUG
  100.     printk("ths_free_sektor : 0x%lx\n",tbf->sektnr[0]);
  101. #endif
  102.  
  103.     if(tbf->dirty != 0)
  104.         printk("read-only\n");
  105.     kfree_s(tbf->data[0],512);
  106.     tbf->data[0]=NULL;
  107.     tbf->dirty=0;
  108.     tbf->sektore=0;
  109.     tbf->hl[0]=0;
  110. }
  111.  
  112.  
  113. /*
  114.  * Lesen eines Clusters
  115.  */
  116.  
  117. int ths_read_cluster(struct super_block *s, unsigned short cluster, long offset, struct ths_buffer *tbf)
  118. {
  119.     unsigned char *data,*data1=NULL;
  120.     int i,j,k;
  121.     unsigned short cl1,cl2;
  122.     long sektor=0,tmp=0;
  123.     struct ths_sb_info *ths_sb;
  124.     struct buffer_head *bh;
  125.  
  126. #ifdef DEBUG
  127.     printk("ths_read_cluster : %d bei %ld",cluster,offset);
  128. #endif
  129.  
  130.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  131.  
  132.     tbf->sektore = ths_sb->SektorenProCluster;
  133.     tbf->dirty = 0;
  134.  
  135.     j = offset/(ths_sb->SektorenProCluster * 512);
  136.     cl1 = cluster;
  137.     for(i=0;i<j;i++)
  138.     {
  139.         cl2 = (ths_sb->fat[cl1/2048])[cl1%2048];
  140.         cl1 = cl2;
  141.     }
  142.     tbf->cluster = cl1;
  143. #ifdef DEBUG
  144.     printk(" = Cluster %d\n",cl1);
  145. #endif
  146.  
  147.     switch(ths_sb->art)
  148.     {
  149.         case 0:
  150.             sektor = (long)ths_sb->DatenStart;
  151.             sektor += (cl1-2) * ths_sb->SektorenProCluster;
  152.             break;
  153.         case 1:
  154.             tmp = dblsektor(s,cl1);
  155.             sektor = (tmp & 0x1fffff)+1;
  156.             break;
  157.     }
  158. #ifdef DEBUG
  159.     printk("sektor : %ld\n",sektor);
  160. #endif
  161.  
  162.     for(i=0;i<tbf->sektore;i++)
  163.     {
  164.         if(!(tbf->data[i]=(unsigned char *)kmalloc(512,GFP_KERNEL)))
  165.         {
  166.             printk("No Memory left !\n");
  167.             return -1;
  168.         }
  169.     }
  170.     switch(ths_sb->art)
  171.     {
  172.         case 0:
  173.             for(i=0;i<tbf->sektore;i++)
  174.             {
  175.                 if(!(bh = bread(s->s_dev,(sektor+i)>>1,BLOCK_SIZE)))
  176.                 {
  177.                     printk("bread-Fehler\n");
  178.                     return -1;
  179.                 }
  180.                 j=0;
  181.                 if((sektor+i) & 0x01)
  182.                     j = 512;
  183.                 data1 = &(bh->b_data[j]);
  184.  
  185.                 tbf->bnr[i] = (sektor+i)>>1;
  186.                 tbf->sektnr[i] = (sektor+i);
  187.  
  188.                 data = tbf->data[i];
  189.                 for(k=0;k<512;k++)
  190.                 {
  191.                     data[k] = data1[k];
  192.                 }
  193.  
  194.                 brelse(bh);
  195.  
  196.             }
  197.             break;
  198.         case 1:
  199.             if(tmp & 0x40000000)
  200.             {
  201. #ifdef DEBUG
  202.                 printk("Unkomprimiert\n");
  203. #endif
  204.                 for(i=0;i<((tmp & 0x3c000000)>>26)+1;i++)
  205.                 {
  206.                     data1 = ths_uread(s,sektor+i,&bh);
  207.                     tbf->bnr[i] = (sektor+i)>>1;
  208.                     tbf->sektnr[i] = ths_sb->DatenStart+cluster*16+i;
  209.  
  210.                     data = tbf->data[i];
  211.                     for(k=0;k<512;k++)
  212.                     {
  213.                         data[k] = data1[k];
  214.                     }
  215.  
  216.                     brelse(bh);
  217.                 }
  218.             }
  219.             else
  220.             {
  221. #ifdef DEBUG
  222.                 printk("Komprimiert\n");
  223. #endif
  224.                 decompress(s,tbf,tmp);
  225.             }
  226.             break;
  227.     }
  228.     return 0;
  229. }
  230.  
  231.  
  232. /*
  233.  * Freigeben des Speichers nach dem Lesen eines Clusters
  234.  */
  235.  
  236. void ths_free_cluster(struct ths_buffer *tbf)
  237. {
  238.     int i;
  239. #ifdef DEBUG
  240.     printk("ths_free_cluster : %d\n",tbf->cluster);
  241. #endif
  242.  
  243.     if(tbf->dirty != 0)
  244.         printk("read-only\n");
  245.  
  246.     for(i=0;i<tbf->sektore;i++)
  247.     {
  248.         kfree_s(tbf->data[i],512);
  249.         tbf->data[i]=NULL;
  250.         tbf->hl[i]=0;
  251.     }
  252.     tbf->dirty=0;
  253.     tbf->sektore=0;
  254.     tbf->cluster=0;
  255. }
  256.  
  257.  
  258. /*
  259.  * ths_uread_sektor liest einen Sektor von dem angegebenen Device.
  260.  * Es wird der angegebene Sektor gelesen und ein Zeiger auf den
  261.  * Datenpuffer zurueckgegeben. Der belegte Block muss mit brelse(bh)
  262.  * wieder freigegeben werden.
  263.  */
  264.  
  265. char *ths_uread_sektor(long sektor, int dev, struct buffer_head **bh)
  266. {
  267.     int i;
  268. #ifdef DEBUG
  269.     printk("ths_uread_sektor\n");
  270. #endif
  271.     *bh = bread(dev,sektor>>1,BLOCK_SIZE);
  272.     i=0;
  273.     if(sektor&1)
  274.         i=512;
  275.     return &((*bh)->b_data[i]);
  276. }
  277.  
  278.  
  279. /*
  280.  * ths_uread liest einen Sektor aus dem CVF, welcher als offset
  281.  * angegeben wird. Der belegte Block muss durch brelse(bh)
  282.  * wieder freigegeben werden.
  283.  */
  284.  
  285. char *ths_uread(struct super_block *s, long offset, struct buffer_head **bh)
  286. {
  287.     int i,j;
  288.     long sektor;
  289.     unsigned short cluster;
  290.     struct ths_sb_info *ths_sb;
  291.  
  292. #ifdef DEBUG
  293.     printk("ths_uread : %ld\n",offset);
  294. #endif
  295.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  296.  
  297.  
  298.     cluster  = ths_sb->StartCluster;
  299.     j=0;
  300.  
  301.     for(i=0;i<offset/ths_sb->uSektorenProCluster;)
  302.     {
  303.         if(cluster == (ths_sb->cvf[j/2048])[j%2048])
  304.         {
  305.             j++;
  306.             cluster = (ths_sb->cvf[j/2048])[j%2048];
  307.             j++;
  308.         }
  309.         else
  310.         {
  311.             cluster++;
  312.         }
  313.         i++;
  314.     }
  315.     sektor = ths_sb->uDatenStart + (cluster-2)*ths_sb->uSektorenProCluster + (offset % ths_sb->uSektorenProCluster);
  316. #ifdef DEBUG
  317.     printk("Sektor : 0x%lx\n",sektor);
  318. #endif
  319.  
  320.     return ths_uread_sektor(sektor,s->s_dev,bh);
  321. }
  322.  
  323.  
  324. /*
  325.  * dblsektor holt aus der MDFAT-Tabelle den Eintrag
  326.  * eines Clusters und gibt ihn zurueck.
  327.  */
  328.  
  329. long dblsektor(struct super_block *s, unsigned short cluster)
  330. {
  331.     struct buffer_head *bh;
  332.     struct ths_sb_info *ths_sb;
  333.     unsigned char *data,*x;
  334.     int i=0;
  335.     long cl;
  336.  
  337.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  338.  
  339.     cl = (long)(ths_sb->dcluster + cluster )*4;
  340.  
  341.     data = ths_uread(s,ths_sb->MDFATStart+cl/512,&bh);
  342.  
  343.     x = &data[cl%512];
  344.     i= CHL(x);
  345.     brelse(bh);
  346.     return i;
  347. }
  348.  
  349.